/**
 * Created by zheng on 2019/1/3.
 */




export default {
  name: 'ZgLazer',
  props: {
    height: {
      type: Number,
      default: 30
    },
    width: {
      type: Number,
      default: 30
    },
  },
  data(){
    return {
      points: [],
      edges: [],
      ctx: null,
      canvas: null,
      count: 0
    }
  },
  mounted(){

    this.init()
    this.loop()
  },
  render(h){
    return (<canvas ref={"lazer"} width={this.width} height={this.height}></canvas>)
  },
  methods: {
    loop() {
      this.updatePoints()
      if (this.count > 50) {
        this.count = 0
        this.points.push(this.createPoint())
        this.edges.push(this.createEdge())
      }
      else this.count++
      window.requestAnimationFrame(this.loop);
    },
    updatePoints() {
      let canvas = this.$refs.lazer
      let ctx = canvas.getContext('2d');
      ctx.clearRect(0, 0, canvas.height, canvas.width)
      this.points.forEach((point) => {
        if (point.alpha < 1) point.alpha += 0.01
        point.x += point.directX
        point.y += point.directY
        ctx.beginPath();
        ctx.moveTo(point.x, point.y)
        ctx.fillStyle = `rgba(200,200,200,${point.alpha})`;
        // ctx.fillStyle = `rgba(${point.color.r},${point.color.g},${point.color.b},${point.alpha})`;
        ctx.alpha = point.alpha
        ctx.arc(point.x, point.y, 2, 0, 2 * Math.PI)
        ctx.fill()
      })
      this.edges.forEach((edge) => {
        if (edge.alpha < 1 && edge.status === 0) {
          edge.alpha += 0.01
        } else if (edge.alpha >= 1 && edge.status === 0) {
          edge.status = 1
        }
        else if (edge.status >= 1 && edge.status <= 200) {
          edge.status += 1
        }
        else if (edge.status >= 200 && edge.alpha >= 0) {
          edge.alpha -= 0.01
        }

        ctx.beginPath()
        ctx.moveTo(this.points[edge.from].x, this.points[edge.from].y)
        let grad = ctx.createLinearGradient(this.points[edge.from].x, this.points[edge.from].y, this.points[edge.to].x, this.points[edge.to].y)
        grad.addColorStop(0, `rgba(${this.points[edge.from].color.r},${this.points[edge.from].color.g},${this.points[edge.from].color.b},${edge.alpha})`)
        grad.addColorStop(edge.count, `rgba(${this.points[edge.to].color.r},${this.points[edge.to].color.g},${this.points[edge.to].color.b},${edge.alpha})`)
        grad.addColorStop(edge.count+0.01, `rgba(${this.points[edge.to].color.r},${this.points[edge.to].color.g},${this.points[edge.to].color.b},0)`)
        grad.addColorStop(1, `rgba(${this.points[edge.to].color.r},${this.points[edge.to].color.g},${this.points[edge.to].color.b},0)`)
        ctx.strokeStyle = grad
        ctx.lineWidth = 2
        ctx.shadowBlur = 3
        ctx.shadowColor = 'rgba(255,255,255,0.3)'
        ctx.lineTo(this.points[edge.to].x, this.points[edge.to].y)
        ctx.stroke()

        if(edge.count<0.99)edge.count+=0.01
      })
      this.deleteUnusedEdgeAndPoint()
      // this.points = this.points.filter(point => this.isInRect(point))
    },
    deleteUnusedEdgeAndPoint(){
      this.edges = this.edges.filter(edge => edge.alpha > 0)
      let updatePointIndexMap = {}
      let deleteCount = 0
      this.points.forEach((point, index) => {
        if (this.edges.some(edge => {
            return edge.from === index || edge.to === index
          })) {
          updatePointIndexMap[index] = index - deleteCount
        } else {
          if (!this.isInRect(point)) {
            deleteCount += 1
            point.status = 1
          } else {
            updatePointIndexMap[index] = index - deleteCount
          }
        }
      })
      this.edges = this.edges.map(edge => {
        edge.from = updatePointIndexMap[edge.from]
        edge.to = updatePointIndexMap[edge.to]
        return edge
      })
      this.points = this.points.filter(point => point.status === 0)
      console.log('point:', this.points.length, '   edge:', this.edges.length)
    },
    isInRect(point){
      let canvas = this.$refs.lazer
      if (point.x >= 0 && point.x <= canvas.width && point.y >= 0 && point.y <= canvas.height)
        return true
      return false
    },
    init() {
      for (let i = 0; i < 50; i++) {
        this.points.push(this.createPoint())
      }
    },
    createEdge(){
      let edge = {}
      edge.from = Math.floor(this.points.length * Math.random())
      edge.to = Math.floor(this.points.length * Math.random())
      edge.status = 0
      edge.count = 0
      edge.alpha = 0.1
      return edge
    },
    createPoint(){
      let point = {}
      point.x = this.width * Math.random();
      point.y = this.height * Math.random();
      point.color = {};
      point.status = 0
      point.color.r = Math.floor(255 * Math.random())
      point.color.g = Math.floor(255 * Math.random())
      point.color.b = Math.floor(255 * Math.random())
      point.directX = 2 * Math.random() - 1
      point.directY = 2 * Math.random() - 1
      point.alpha = 0.1
      return point
    }
  },
}
